package stream;

import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Author:ZouHeng
 * Description:
 * Date:2021-07-06  10:59
 **/
public class StreamTest {

    /**
     * 传统的遍历
     */
    @Test
    public void oldIterator() {
        List<String> list = createNameList();
        for (String item: list) {
            System.out.println(item);
        }
    }

    /**
     * 传统的过滤子集
     */
    @Test
    public void oldFilteredSub() {
        List<String> list = createNameList();
        List<String> zhangList = new ArrayList<>();
        for (String name : list) {
            if (name.startsWith("张")) {
                zhangList.add(name);
            }
        }
        List<String> shortList = new ArrayList<>();
        for (String name : zhangList) {
            if (name.length() == 3) {
                shortList.add(name);
            }
        }
        for (String name : shortList) {
            System.out.println(name);
        }
    }

    /**
     * JDK8利用Stream过滤子集
     */
    @Test
    public void streamFilteredSub() {
        List<String> list = createNameList();
        list.stream().filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3).forEach(System.out::println);
    }

    @Test
    public void getStream() {
        //根据Collection获取流
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();
        Set<String> set = new HashSet<>();
        Stream<String> stream2 = set.stream();

        //根据Map获取流
        //java.util.Map 接口不是 Collection 的子接口，且其K-V数据结构不符合流元素的单一特征，所以获取对应的流
        //需要分key、value或entry等情况：
        Map<String, String> map = new HashMap<>();
        Stream<String> keyStream = map.keySet().stream();
        Stream<String> valueStream = map.values().stream();
        Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();

        //根据数组获取流
        String[] array = {"张无忌", "张翠山", "张三丰", "张一元"};
        Stream<String> stream = Stream.of(array);
    }

    /**
     * 逐一处理：forEach
     */
    @Test
    public void testForEach() {
        List<String> list = createNameList();
        list.forEach(System.out::println);
    }

    /**
     * 过滤：filter
     * 可以通过 filter 方法将一个流转换成另一个子集流
     */
    @Test
    public void testFilter() {
        List<String> list = createNameList();
        list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
    }

    /**
     * 映射：map
     * 如果需要将流中的元素映射到另一个流中，可以使用 map 方法
     */
    @Test
    public void testMap() {
        Stream<String> original = Stream.of("10", "12", "18");
        Stream<Integer> result = original.map(str -> Integer.parseInt(str));
    }

    /**
     * 统计个数：count
     */
    @Test
    public void testCount() {
        List<String> list = createNameList();
        long count = list.stream().count();
        System.out.println(count);
    }

    /**
     * 取用前几个：limit
     */
    @Test
    public void testLimit() {
        createNameList().stream().limit(3).forEach(System.out::println);
    }

    /**
     * 跳过前几个：skip
     */
    @Test
    public void testSkip() {
        createNameList().stream().skip(3).forEach(System.out::println);
    }

    /**
     * 组合：concat
     */
    @Test
    public void testConcat() {
        List<String> list1 = createNameList();
        List<String> list2 = Stream.of("科比", "詹姆斯", "韦德", "乔丹").collect(Collectors.toList());
        Stream.concat(list1.stream(), list2.stream()).forEach(System.out::println);
    }

    /**
     * 现在有两个 ArrayList 集合存储队伍当中的多个成员姓名，要求使用传统的for循环（或增强for循环）依次进行以下若干操作步骤：
     * 1. 第一个队伍只要名字为3个字的成员姓名；存储到一个新集合中。
     * 2. 第一个队伍筛选之后只要前3个人；存储到一个新集合中。
     * 3. 第二个队伍只要姓张的成员姓名；存储到一个新集合中。
     * 4. 第二个队伍筛选之后不要前2个人；存储到一个新集合中。
     * 5. 将两个队伍合并为一个队伍；存储到一个新集合中。
     * 6. 根据姓名创建 Person 对象；存储到一个新集合中。
     * 7. 打印整个队伍的Person对象信息。
     */
    @Test
    public void practice() {
        ArrayList<String> one = new ArrayList<>();
        one.add("迪丽热巴");
        one.add("宋远桥");
        one.add("苏星河");
        one.add("石破天");
        one.add("石中玉");
        one.add("老子");
        one.add("庄子");
        one.add("洪七公");
        ArrayList<String> two = new ArrayList<>();
        two.add("古力娜扎");
        two.add("张无忌");
        two.add("赵丽颖");
        two.add("张三丰");
        two.add("尼古拉斯赵四");
        two.add("张天爱");
        two.add("张二狗");

        Stream<String> totalStream = Stream.concat(one.stream(), two.stream());
        List<String> list1 = totalStream.filter(s -> s.length() == 3).collect(Collectors.toList());
        List<String> list2 = list1.stream().limit(3).collect(Collectors.toList());
        List<String> list3 = totalStream.filter(s -> s.startsWith("张")).collect(Collectors.toList());
        List<String> list4 = list3.stream().skip(2).collect(Collectors.toList());
        List<String> list5 = totalStream.collect(Collectors.toList());
    }


    private List<String> createNameList() {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        return list;
    }
}
